package org.mysfit.ctp4j.infra.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.mysfit.ctp4j.api.vo.BonsVO;
import org.mysfit.ctp4j.api.vo.QuoteVO;
import org.mysfit.ctp4j.api.vo.ReqVO;
import org.mysfit.ctp4j.api.vo.TradeVO;
import org.mysfit.ctp4j.infra.enums.RequestTypeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 操作系统信息判断工具类
 * 
 * @author long.gf
 *
 */
public class TradeCurrUser {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(TradeCurrUser.class);

	public static int D_FX = 1;

	public static int K_FX = -1;
	
	public static int K_FLAG = 0;

	public static int P_FLAG = 1;

	public static int QUOTE_OK_STATUS = 0;
	
	public static int TRADE_HALF_OK_STATUS = 1;

	public static int TRADE_OK_STATUS = 2;
	
	public static List<ReqVO> REQUEST_LIST = new ArrayList<ReqVO>();

	public static Map<Integer,ReqVO> REQUEST_MAP = new HashMap<Integer,ReqVO>();
	
	public static Map<String,Map<String,QuoteVO>> QUOTE_MAP = new HashMap<String,Map<String,QuoteVO>>();

	public static Map<String,Map<String,BonsVO>> BONS_MAP = new HashMap<String,Map<String,BonsVO>>();
	
	public static boolean isKC(int flag) {
		return K_FLAG == flag;
	}
	
	public static boolean isDF(int flag) {
		return D_FX == flag;
	}
	
	public static void addReqVO(ReqVO newVO) {
		REQUEST_LIST.add(newVO);
	}
	
	public static QuoteVO checkQuoteId(String fid) {
		if(null != QUOTE_MAP.get(fid)) {
			for (QuoteVO q : QUOTE_MAP.get(fid).values()) {
				 if(q.getTradeStatus() != TRADE_OK_STATUS) {
					 return q;
				 }
			}
		}
		return null;
	}
	
	public static void addQuoteReq(QuoteVO q) {
		ReqVO newVO = TradeConvertUtils.initQuoteReqVO(q);
		newVO.setRequestType(RequestTypeEnum.QUTOE.getTypeName());
		newVO.setRequestTime(TradeTimeUtils.getCurrTime());
		REQUEST_MAP.put(q.getRequestId(), newVO);
		addReqVO(newVO);
	}
	
	public static void addCancleReq(QuoteVO q) {
		ReqVO newVO = TradeConvertUtils.initQuoteReqVO(q);
		newVO.setRequestType(RequestTypeEnum.CANCLE.getTypeName());
		newVO.setRequestTime(TradeTimeUtils.getCurrTime());
		REQUEST_MAP.put(q.getRequestId(), newVO);
		addReqVO(newVO);
	}
	
	public static void addQuoteRtnReq(QuoteVO q) {
		ReqVO newVO = TradeConvertUtils.initQuoteReqVO(q);
		newVO.setRequestType(RequestTypeEnum.QUTOE_RTN.getTypeName());
		newVO.setRequestTime(TradeTimeUtils.getCurrTime());
		addReqVO(newVO);
	}
	
	public static void addCancleRtnReq(QuoteVO q) {
		ReqVO newVO = TradeConvertUtils.initQuoteReqVO(q);
		newVO.setRequestType(RequestTypeEnum.CANCLE_RTN.getTypeName());
		newVO.setRequestTime(TradeTimeUtils.getCurrTime());
		addReqVO(newVO);
	}
	
	public static void addTradeRtnReq(TradeVO t) {
		ReqVO newVO = TradeConvertUtils.initTradeReqVO(t);
		newVO.setRequestType(isKC(t.getKpFlag()) ?  RequestTypeEnum.TRADE_KC_RTN.getTypeName() : RequestTypeEnum.TRADE_PC_RTN.getTypeName());
		newVO.setRequestTime(TradeTimeUtils.getCurrTime());
		addReqVO(newVO);
	}
	
	public static void addQuote(QuoteVO q) {
		String fid= q.getFid();
		String quoteId = q.getQuoteId();
		q.setTradeStatus(QUOTE_OK_STATUS);
		Map<String,QuoteVO> quoteMap = QUOTE_MAP.get(fid);
		if(null == quoteMap) {
			quoteMap = new HashMap<String, QuoteVO>();
		} 
		quoteMap.put(quoteId, q);
		QUOTE_MAP.put(fid, quoteMap);
		addQuoteRtnReq(q);
	}
	
	public static void addTrade(TradeVO t) {
		String fid= t.getFid();
		String quoteId = t.getQuoteId();
		QuoteVO q = QUOTE_MAP.get(fid).get(quoteId);
		q.getTradeList().add(t);
		int tradeCount = q.getTradeList().stream().mapToInt(TradeVO::getQty).sum();
		q.setTradeStatus(tradeCount < q.getQty() ? TRADE_HALF_OK_STATUS : TRADE_OK_STATUS);
		addTradeRtnReq(t);
		addBons(t);
	}
	
	public static void addBons(TradeVO t) {
		String fid= t.getFid();
		String quoteId = isKC(t.getKpFlag()) ? t.getQuoteId() : t.getRefQuoteId();
		Map<String,BonsVO> bonsMap = BONS_MAP.get(fid);
		if(null == bonsMap) {
			bonsMap = new HashMap<String, BonsVO>();
			BONS_MAP.put(fid, bonsMap);
		}
		BonsVO bo = bonsMap.get(quoteId);
		if(null == bo) {
			bo = new BonsVO();
			bo.setFid(fid);
			bo.setQuoteId(quoteId);
			bo.setFtime(t.getFtime());
			bo.setCost(t.getCost());
			bo.setQty(t.getQty());
			BONS_MAP.get(fid).put(quoteId, bo);
			return ;
		}
		int bCount = bo.getQty();
		int tCount = t.getQty();
		if(isKC(t.getKpFlag())) {
			bo.setQty(bCount + tCount);
			bo.setCost(Math.round((bo.getCost()*bCount + t.getCost()*tCount)/(bCount + tCount)));
		}else {
			bo.setQty(bCount - tCount);
		}
		if(bo.getQty() == 0) {
			BONS_MAP.get(fid).remove(quoteId);
			for (ReqVO reqVO : REQUEST_LIST) {
				LOGGER.info(reqVO.getRequestTime() + ":" + reqVO.getRequestType()+";" +reqVO.toString() );
			}
		}
	}
	
}
